using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace WMVConvert.Metadata
{
	public enum PictureType
	{
		Unknown = 0, // Picture of a type not specifically listed in this table 
		PNGIcon = 1, // 32 pixel by 32 pixel file icon. Use only with portable network graphics (PNG) format 
		Icon = 2, // File icon not conforming to type 1 above 
		FrontAlbumCover = 3, // Front album cover 
		BackAlbumCover = 4, // Back album cover 
		LeafletPage = 5, // Leaflet page 
		Media = 6, // Media. Typically this type of image is of the label side of a CD 
		LeadArtist = 7, // Picture of the lead artist, lead performer, or soloist 
		Artists = 8, // Picture of one of the artists or performers 
		Conductor = 9, // Picture of the conductor 
		Band = 10, // Picture of the band or orchestra 
		Composer = 11, // Picture of the composer 
		Writer = 12, // Picture of the lyricist or writer 
		RecordingLocation = 13, // Picture of the recording studio or location 
		RecordingSession = 14, // Picture taken during a recording session 
		LivePerformance = 15, // Picture taken during a performance 
		ScreenCapture = 16, // Screen capture from a movie or video 
		ColoredFish = 17, // A bright colored fish 
		Illustration = 18, // Illustration 
		BandLogo = 19, // Logo of the band or artist 
		PublisherLogo = 20 // Logo of the publisher or studio 
	}

	public class WMPicture : WMBinary<Structures.WM_Picture>
	{
		private string mimeType;
		public string MimeType
		{
			get { return mimeType; }
		}

		private PictureType pictureType;
		public PictureType PictureType
		{
			get { return pictureType; }
		}

		private string description;

		private Image image;
		public Image Image
		{
			get { return image; }
		}

		public const PictureType PictureTypeDefault = PictureType.Media;

		public WMPicture()
			: this(PictureTypeDefault, Properties.Resources.EmptyImage)
		{
		}

		public WMPicture(string fileName)
			: this(PictureTypeDefault, Image.FromFile(fileName))
		{
		}

		public WMPicture(Image image)
			: this(PictureTypeDefault, image)
		{
		}

		public WMPicture(PictureType pictureType,Image image)
            :base()
		{
			this.mimeType = "image/jpeg";
			this.pictureType = pictureType;
			this.description = string.Empty;
			this.image = image;
		}

		public WMPicture(IntPtr valueData, uint valueDataLength)
            :base(valueData, valueDataLength)
		{
			Structures.WM_Picture rawPicture = (Structures.WM_Picture)Marshal.PtrToStructure(valueData, typeof(Structures.WM_Picture));
			this.mimeType = Marshal.PtrToStringUni(rawPicture.pwszMIMEType);
			this.pictureType = (PictureType)rawPicture.bPictureType;
			this.description = Marshal.PtrToStringUni(rawPicture.pwszDescription);
			byte[] data = new byte[rawPicture.dwDataLen];
			Marshal.Copy(rawPicture.pbData, data, 0, rawPicture.dwDataLen);
			this.image = (Image)new ImageConverter().ConvertFrom(data);
		}

		protected override Structures.WM_Picture GetData()
		{
			Structures.WM_Picture rawPicture = new Structures.WM_Picture();
			rawPicture.pwszDescription = Marshal.StringToCoTaskMemUni(this.description);
			rawPicture.bPictureType = (byte)this.PictureType;
			rawPicture.pwszMIMEType = Marshal.StringToCoTaskMemUni(this.MimeType);
			byte[] data = (byte[])new ImageConverter().ConvertTo(Image, typeof(byte[]));
			rawPicture.dwDataLen = (int)data.Length;
			rawPicture.pbData = Alloc(rawPicture,rawPicture.dwDataLen);
			Marshal.Copy(data, 0, rawPicture.pbData, rawPicture.dwDataLen);
			return rawPicture;
		}
	}
}
